package com.gitee.wsl.flow.multicast.channel

/**
 * Buffer implementation for any late arrivals.
 */
internal interface Buffer<T> {
    fun add(item: Message.Dispatch.Value<T>)
    fun isEmpty() = items.isEmpty()
    val items: Collection<Message.Dispatch.Value<T>>
}

/**
 * Default implementation of buffer which does not buffer anything.
 */
internal class NoBuffer<T> : Buffer<T> {
    override val items: Collection<Message.Dispatch.Value<T>>
        get() = emptyList()

    // ignore
    override fun add(item: Message.Dispatch.Value<T>) = Unit
}

/**
 * Create a new buffer insteance based on the provided limit.
 */
@Suppress("FunctionName")
internal fun <T> Buffer(limit: Int): Buffer<T> = if (limit > 0) {
    BufferImpl(limit)
} else {
    NoBuffer()
}

/**
 * A real buffer implementation that has a FIFO queue.
 */
internal class BufferImpl<T>(private val limit: Int) :
    Buffer<T> {
    override val items = ArrayDeque<Message.Dispatch.Value<T>>(limit.coerceAtMost(10))
    override fun add(item: Message.Dispatch.Value<T>) {
        while (items.size >= limit) {
            items.removeFirst()
        }
        items.addLast(item)
    }
}